package com.dynamic.mybatis.core.generator;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.SqlCondition;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.dynamic.mybatis.core.metadata.MappedStatementField;
import com.dynamic.mybatis.core.metadata.MappedStatementMetaField;
import com.dynamic.mybatis.core.metadata.MappedStatementTable;

import java.util.Optional;

/**
 * @Description
 * @Author xs
 * @Date 2023/4/14 10:55
 */
public class InjectorHelper implements Constants {

    /**
     * 表字段是否启用了插入填充
     *
     * @since 3.3.0
     */
    protected static boolean withInsertFill;
    /**
     * 表字段是否启用了更新填充
     *
     * @since 3.3.0
     */
    protected static boolean withUpdateFill;
    /**
     * 　* 属性字段前缀
     *
     */
    protected static String fieldPrefix;
    /**
     * 属性表达式#{property}, 可以指定jdbcType, typeHandler等
     */
    protected static String el;


    /**
     * 字段验证策略之 insert
     *
     * @since 3.1.2
     */
    protected static FieldStrategy insertStrategy = FieldStrategy.NOT_NULL;
    /**
     * 字段验证策略之 update
     *
     * @since 3.1.2
     */
    protected static FieldStrategy updateStrategy = FieldStrategy.NOT_NULL;

    /**
     * 字段验证策略之 where
     * Refer to {@link TableField#whereStrategy()}
     *
     * @since added v_3.1.2 @2019-5-7
     */
    protected static FieldStrategy whereStrategy = FieldStrategy.NOT_NULL;

    /**
     * where 字段比较条件
     */
    protected static String condition = SqlCondition.EQUAL;
    /**
     * 字段填充策略
     */
    protected static FieldFill fieldFill = FieldFill.DEFAULT;

    /**
     * 主键是否有存在字段名与属性名关联
     * <p>true: 表示要进行 as</p>
     */
    protected static boolean keyRelated;


    /**
     * SQL 注释
     *
     * @return sql
     */
    public static String sqlComment() {
        return "";
        // return convertIfEwParam(Q_WRAPPER_SQL_COMMENT, true);
    }

    /**
     * SQL 注释
     *
     * @return sql
     */
    public static String sqlFirst() {
        return "";
        //return convertIfEwParam(Q_WRAPPER_SQL_FIRST, true);
    }


    protected static String convertIfProperty(String prefix, String property) {
        return StringUtils.isNotBlank(prefix) ? prefix.substring(0, prefix.length() - 1) + "['" + property + "']" : property;
    }

    protected static String convertIfEwParam(final String param, final boolean newLine) {
        return SqlScriptUtils.convertIf(SqlScriptUtils.unSafeParam(param),
                String.format("%s != null and %s != null", WRAPPER, param), newLine);
    }


    /**
     * 转换成 if 标签的脚本片段
     *
     * @param sqlScript     sql 脚本片段
     * @param property      字段名
     * @param fieldStrategy 验证策略
     * @return if 脚本片段
     */
    public static String convertIf(MappedStatementField field, final String sqlScript, final String property, final FieldStrategy fieldStrategy) {
        if (fieldStrategy == FieldStrategy.NEVER) {
            return null;
        }
        if (field.getJavaTypeClass().isPrimitive() || fieldStrategy == FieldStrategy.IGNORED) {
            return sqlScript;
        }
        if (fieldStrategy == FieldStrategy.NOT_EMPTY && field.getJavaTypeClass().equals(String.class)) {
            return SqlScriptUtils.convertIf(sqlScript, String.format("%s != null and %s != ''", property, property),
                    false);
        }
        return SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", property), false);
    }


    public static String getFirstKeyColumn(MappedStatementTable table) {
        return getFirstKeyField(table).map(MappedStatementField::getColumn).orElse(null);

    }

    public static Optional<MappedStatementMetaField> getFirstKeyField(MappedStatementTable table) {
        return table.getFields().stream().filter(MappedStatementField::isPrimaryKey).findFirst();
    }

    public static Optional<MappedStatementMetaField> getLogicDelete(MappedStatementTable table) {
        return table.getFields().stream().filter(MappedStatementMetaField::isLogicDelete).findFirst();
    }

    public static Optional<MappedStatementMetaField> getOptimisticLock(MappedStatementTable table) {
        return table.getFields().stream().filter(MappedStatementMetaField::isOptimisticLock).findFirst();
    }

}